package com.ruoyi.common.utils;

import cn.hutool.core.util.IdUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.ruoyi.common.convert.ExcelBigNumberConvert;
import com.ruoyi.common.excel.CellMergeStrategy;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.List;

/**
 * @program: lgy-ry-flowable
 * @description:
 * @author: lgy
 * @create: 2025-02-20 17:12
 **/
public class ExcelUtils<T> extends ExcelUtil<T> {
    public ExcelUtils(Class<T> clazz) {
        super(clazz);
    }
    /**
     * 导出excel
     *
     * @param list      导出数据集合
     * @param sheetName 工作表的名称
     * @param clazz     实体类
     * @param response  响应体
     */
    public static <T> void exportExcel(List<T> list, String sheetName, Class<T> clazz, HttpServletResponse response) {
        try {
            // 重置响应体、设置响应头信息
            resetResponse(sheetName, response);
            // 获取输出流
            ServletOutputStream os = response.getOutputStream();
            // 导出文件
            exportExcel(list, sheetName, clazz, false, os);
        } catch (IOException e) {
            throw new RuntimeException("导出Excel异常");
        }
    }
    /**
     * 重置响应体、设置响应头信息
     */
    private static void resetResponse(String sheetName, HttpServletResponse response) throws UnsupportedEncodingException {
        // 设置文件名
        String filename = encodingFilename2(sheetName);
        // 文件下载请求头处理
        FileUtils.setAttachmentResponseHeader(response, filename);
        // 设置响应的 Content-Type 头信息，以明确响应内容的 MIME 类型。
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
    }
    /**
     * 编码文件名
     */
    public static String encodingFilename2(String filename) {
        return IdUtil.fastSimpleUUID() + "_" + filename + ".xlsx";
    }
    /**
     * 导出excel
     *
     * @param list      导出数据集合
     * @param sheetName 工作表的名称
     * @param clazz     实体类
     * @param merge     是否合并单元格
     * @param os        输出流
     */
    public static <T> void exportExcel(List<T> list, String sheetName, Class<T> clazz, boolean merge, OutputStream os) {
        // 使用EasyExcel进行导出，指定实体类限制了输出的列，实体类上@ExcelProperty注解即列名称
        ExcelWriterSheetBuilder builder = EasyExcel.write(os, clazz)
                .autoCloseStream(false)
                // 自动适配
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                // 大数值自动转换 防止失真
                .registerConverter(new ExcelBigNumberConvert())
                // 工作表名称
                .sheet(sheetName);
        if (merge) {
            // 合并处理器
            builder.registerWriteHandler(new CellMergeStrategy(list, true));
        }
        builder.doWrite(list);
    }
}
